﻿using System;
using System.Collections;
using System.Collections.Specialized;
using System.Linq.Expressions;
using Castle.MonoRail.Framework;

namespace Castle.MonoRail.ExtensionMethods {
	public static class ControllerExtensions {
		public static IControllerExtensionsProvider Provider { get; set; }

		static ControllerExtensions() {
			Provider = new DefaultExtensionsProvider();
		}

		public static void RedirectToAction<T>(this T c, Expression<Action<T>> action) where T : SmartDispatcherController {
			Provider.RedirectToAction(c, action);
		}

		public static void RedirectToAction<T>(this T c, Expression<Func<T, Action>> action) where T : Controller {
			Provider.RedirectToAction(c, action);
		}

		public static void RedirectToAction<T>(this T c, Expression<Func<T, Action>> action, IDictionary parameters) where T : Controller {
			Provider.RedirectToAction(c, action, parameters);
		}

		public static void RedirectToAction<T>(this T c, Expression<Func<T, Action>> action, NameValueCollection parameters) where T : Controller {
			Provider.RedirectToAction(c, action, parameters);
		}

		public static void RedirectToAction<T>(this T c, Expression<Func<T, Action>> action, string[] parameters) where T : Controller {
			throw new NotImplementedException();
		}

		public static void RedirectToAction<T, R>(this T c, Expression<Func<T, Action<R>>> action) where T : Controller {
			Provider.RedirectToAction(c, action);
		}

		public static void RedirectToAction<T, R1, R2>(this T c, Expression<Func<T, Action<R1, R2>>> action) where T : Controller {
			Provider.RedirectToAction(c, action);
		}

		public static void RedirectToAction<T, R1, R2, R3>(this T c, Expression<Func<T, Action<R1, R2, R3>>> action) where T : Controller {
			Provider.RedirectToAction(c, action);
		}

		public static void RedirectToAction<T, R1, R2, R3, R4>(this T c, Expression<Func<T, Action<R1, R2, R3, R4>>> action) where T : Controller {
			Provider.RedirectToAction(c, action);
		}

		public static void Redirect<T>(this Controller c, string action) where T : Controller {
			Provider.Redirect<T>(c, action);
		}

		public static void Redirect<T>(this Controller c, Expression<Action<T>> action) where T : SmartDispatcherController {
			Provider.Redirect(c, action);
		}

		public static void Redirect<T>(this Controller c, Expression<Func<T, Action>> action) where T : Controller {
			Provider.Redirect(c, action);
		}

		public static void Redirect<T, R>(this Controller c, Expression<Func<T, Action<R>>> action) where T : Controller {
			Provider.Redirect(c, action);
		}

		public static void Redirect<T, R1, R2>(this Controller c, Expression<Func<T, Action<R1, R2>>> action) where T : Controller {
			Provider.Redirect(c, action);
		}

		public static void Redirect<T, R1, R2, R3>(this Controller c, Expression<Func<T, Action<R1, R2, R3>>> action) where T : Controller {
			Provider.Redirect(c, action);
		}

		public static void Redirect<T, R1, R2, R3, R4>(this Controller c, Expression<Func<T, Action<R1, R2, R3, R4>>> action) where T : Controller {
			Provider.Redirect(c, action);
		}

		public static void Redirect<T>(this Controller c, string action, IDictionary parameters) where T : Controller {
			Provider.Redirect<T>(c, action, parameters);
		}

		public static void Redirect<T>(this Controller c, string action, NameValueCollection parameters) where T : Controller {
			Provider.Redirect<T>(c, action, parameters);
		}

		public static void RenderView<T>(this Controller c, string name) where T : Controller {
			Provider.RenderView<T>(c, name);
		}

		public static void RenderView<T>(this Controller c, string name, string mimeType) where T : Controller {
			Provider.RenderView<T>(c, name, mimeType);
		}

		public static void RenderView<T>(this Controller c, string name, bool skipLayout) where T : Controller {
			Provider.RenderView<T>(c, name, skipLayout);
		}

		public static void RenderView<T>(this Controller c, string name, bool skipLayout, string mimeType)
			where T : Controller {
			Provider.RenderView<T>(c, name, skipLayout, mimeType);
		}
	}
}